#include "Mutex.hpp"
#include <stdio.h>
#include <unistd.h>
#include "Thread.hpp"
#include<vector>

using namespace MutexModule;
using namespace ThreadModule;

// 创建四个线程
const int num = 4;

// 将该对象传递给Routine作为参数
class ThreadData
{
public:
    ThreadData(const std::string &name, Mutex &mutex)
        : _name(name), _mutex(&mutex)
    {
    }
    ~ThreadData()
    {
    }
    std::string _name;
    Mutex* _mutex;
};

int ticket = 1000;

void *Routine(void *arg)
{
    ThreadData *td = static_cast<ThreadData *>(arg);

    while (1)
    {
        {
            LockGuard lockguard(*td->_mutex);
            if (ticket > 0)
            {
                usleep(1000);
                printf("%s sells ticket: %d\n", td->_name.c_str(), ticket);
                ticket--;
            }
            else
            {
                break;
            }
        }
    }
    return nullptr;
}


Mutex mutex;

int main()
{
    // 先创建一把锁
    // Mutex mutex;

    // 创建四个线程
    pthread_t t1, t2, t3, t4;

    ThreadData td1("thread-1", mutex);
    ThreadData td2("thread-2", mutex);
    ThreadData td3("thread-3", mutex);
    ThreadData td4("thread-4", mutex);

    //Thread t_1([&td1](){
    //    Routine(&td1);
    //});

    
    //Thread t_2([&td2](){
    //    Routine(&td2);
    //});
    //Thread t_3([&td3](){
    //    Routine(&td3);
    //});
    //Thread t_4([&td4](){
    //    Routine(&td4);
    //});

    //t_4.Start();
    //t_1.Start();
    //t_2.Start();
    //t_3.Start();

    //t_1.Join();
    //t_2.Join();
    //t_3.Join();
    //t_4.Join();
    //std::vector<Thread*> ret;
    //for (int i = 1; i <= num; i++)
    //{
    //    char buffer[128];
    //    snprintf(buffer, sizeof(buffer), "thread-%d", i);
    //    ThreadData* td = new ThreadData(buffer, mutex);
    //    Thread* t = new Thread([&td](){
    //        Routine(td);
    //    });

    //    // 上面是创建好线程，下面是要启动和等待
    //    // t->Start();
    //    // sleep(1);
    //    // t->Detach();
    //    ret.push_back(t);
    //}

    //for (auto& s : ret)
    //{
    //    s->Start();
    //    s->Join();
    //}


    pthread_create(&t1, nullptr, Routine, &td1);
    pthread_create(&t2, nullptr, Routine, &td2);
    pthread_create(&t3, nullptr, Routine, &td3);
    pthread_create(&t4, nullptr, Routine, &td4);

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);

    return 0;
}